package com.ccsu.joysport.service;

import ch.qos.logback.core.util.StringUtil;
import com.ccsu.joysport.controller.model.resp.ClubPageResp;
import com.ccsu.joysport.dto.*;
import com.ccsu.joysport.entity.*;
import com.ccsu.joysport.repository.*;
import com.ccsu.joysport.util.JwtUtil;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ClubService {
    @Autowired
    private ClubRepository clubRepository;
    @Autowired
    private ClubApplicationRepository clubApplicationRepository;
    @Autowired
    private ActivityRepository activityRepository;
    @Autowired
    private StudentClubRepository studentClubRepository;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private StudentRepository studentRepository;
    @Autowired
    private StudentActivityRepository studentActivityRepository;


    public Club getClubDetail(String clubId) {
        Club club = clubRepository.findById(clubId)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到俱乐部"));

        // 更新 memberCount
        int memberCount = studentClubRepository.countMembersByClubId(clubId);
        club.setMemberCount(memberCount);

        return club;
    }


    public ApplyJoinClubResponse applyJoinClub(ApplyJoinClubRequest request) {

        String StuId;
        try {
            StuId = jwtUtil.extractId(request.getToken());
        } catch (JwtException e) {
            return new ApplyJoinClubResponse("failed", "token解析失败");
        }
        Club club = clubRepository.findById(request.getClubId())
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到俱乐部"));

        // 检查是否已经存在相同的学生ID和俱乐部ID的申请记录
        if (clubApplicationRepository.findByClubIdAndStudentId(request.getClubId(), StuId).isPresent()) {
            return new ApplyJoinClubResponse("wait", "已经申请，请等待管理员同意");
        }

        ClubApplication application = new ClubApplication();
        application.setStudentId(StuId);
        application.setClubId(request.getClubId());
        application.setReason(request.getReason());
        application.setStatus("wait");
        application.setApplicationTime(Timestamp.from(Instant.now()));
        clubApplicationRepository.save(application);

        return new ApplyJoinClubResponse("wait", "申请已提交，请等待管理员审核");
    }

    public List<ClubActivityResponse> getClubActivities(String clubId) {
        // 查询俱乐部信息
        Club club = clubRepository.findById(clubId)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到关联的俱乐部"));

        // 获取俱乐部的活动列表
        List<Activity> activities = activityRepository.findByClubId(clubId);

        // 获取每个活动的ID
        List<String> activityIds = activities.stream().map(Activity::getActivityId).collect(Collectors.toList());

        // 查询每个活动的报名人数
        List<StudentActivity> studentActivityList = studentActivityRepository.findByActivityIdIn(activityIds);
        Map<String, Long> activityIdAndCountMap = studentActivityList.stream()
                .collect(Collectors.groupingBy(StudentActivity::getActivityId, Collectors.counting()));

        // 创建响应列表
        List<ClubActivityResponse> responses = activities.stream().map(activity -> {
            // 格式化时间字段
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String activityTimeStartFormatted = dateFormat.format(activity.getActivityTimeStart());
            String activityTimeEndFormatted = dateFormat.format(activity.getActivityTimeEnd());

            // 计算剩余可报名人数
            int activityMax = activity.getActivityMax();
            long registeredCount = activityIdAndCountMap.getOrDefault(activity.getActivityId(), 0L);
            int remainingSpots = activityMax - (int) registeredCount;
            boolean canRegister = remainingSpots > 0;

            // 设置活动状态
            LocalDateTime now = LocalDateTime.now();
            String activityStatus;
            LocalDateTime startTime = activity.getActivityTimeStart().toLocalDateTime();
            LocalDateTime endTime = activity.getActivityTimeEnd().toLocalDateTime();
            if (remainingSpots <= 0) {
                activityStatus = "报名人数已满";
            } else if (now.isBefore(startTime)) {
                activityStatus = "报名中";
            } else if (now.isAfter(endTime)) {
                activityStatus = "已结束";
            } else {
                activityStatus = "进行中";
            }

            return new ClubActivityResponse(
                    activity.getActivityId(),
                    activity.getActivityName(),
                    activity.getActivityDesc(),
                    activity.getActivityImage(),
                    activityTimeStartFormatted,
                    activityTimeEndFormatted,
                    remainingSpots, // 更新 activityMax 为剩余可报名人数
                    activity.getActivityOrganizer(),
                    activity.getClubId(),
                    activity.getActivityPerson(),
                    activity.getActivityPlace(),
                    activityStatus,
                    club.getCollege()
            );
        }).collect(Collectors.toList());

        return responses;
    }


    public List<Club> getJoinedClubs(String token) {

        String StuId = jwtUtil.extractId(token);

        if (!studentClubRepository.existsByStudentId(StuId)) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "学生未找到");
        }
        List<StudentClub> studentClubs = studentClubRepository.findByStudentId(StuId);
        List<String> clubIds = studentClubs.stream().map(StudentClub::getClubId).collect(Collectors.toList());
        List<Club> clubs = clubRepository.findAllById(clubIds);

        // 实时更新每个俱乐部的 memberCount
        clubs.forEach(club -> {
            int memberCount = studentClubRepository.countMembersByClubId(club.getClubId());
            club.setMemberCount(memberCount);
        });
        return clubs;

    }

    public List<Club> searchClub(String query) {
        List<Club> clubs = clubRepository.findByClubNameContainingIgnoreCaseOrClubDescContainingIgnoreCase(query, query);
        clubs.forEach(club -> {
            int memberCount = studentClubRepository.countMembersByClubId(club.getClubId());
            club.setMemberCount(memberCount);
        });
        return clubs;
    }

    public ClubPageResp clubPage(String searchText, Integer pageNum, Integer pageSize) {

        // c端的查询得是审核通过后的俱乐部
        Club club = new Club();
        club.setStatus("approve");

        Example<Club> clubExample = Example.of(club, ExampleMatcher.matching()
                .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact()));

        Page<Club> all;
        if (StringUtil.notNullNorEmpty(searchText)) {
            club.setClubName(searchText);

            clubExample = Example.of(club, clubExample.getMatcher()
                    .withMatcher("clubName", ExampleMatcher.GenericPropertyMatchers.contains()));
        }

        all = clubRepository.findAll(clubExample, PageRequest.of(pageNum, pageSize));

        //更新 memberCount
        all.getContent().forEach(clubItem -> {
            int memberCount = studentClubRepository.countMembersByClubId(clubItem.getClubId());
            clubItem.setMemberCount(memberCount);
        });

        ClubPageResp clubPageResp = new ClubPageResp();
        clubPageResp.setList(all.getContent());
        clubPageResp.setTotalCount((int) all.getTotalElements());

        return clubPageResp;
    }

    public List<ClubApplicationResponse> getApplicationsByStudentId(String token) {
        String StuId = jwtUtil.extractId(token);
        List<ClubApplication> applications = clubApplicationRepository.findByStudentId(StuId);

        return applications.stream().map(app -> new ClubApplicationResponse(
                app.getStudentId(),
                app.getClubId(),
                app.getStatus(),
                app.getApplicationTime(),
                app.getReason(),
                app.getReviewRemark()

        )).collect(Collectors.toList());
    }
    public ClubResponse createClub(CreateClubRequest request) {
        // 解析token获取ID
        String StuId;

        try {
          StuId = jwtUtil.extractId(request.getToken());
        } catch (JwtException e) {
            return new ClubResponse("failed", "token解析失败");
        }
        student student = studentRepository.findByStudentNumber(StuId)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到学生信息"));
        String ClubUserName = student.getName();
        Club club = new Club();
        club.setClubId(request.getClubId());
        club.setClubName(request.getClubName());
        club.setClubDesc(request.getClubDesc());
        club.setClubLogo(request.getClubLogo());
        club.setCollege(request.getCollege());
        club.setClubUser(StuId);
        club.setClubUserName(ClubUserName);
        //学生创建的俱乐部默认等待
        club.setStatus("wait");
        club.setClubCreate(new Timestamp(System.currentTimeMillis()));
        club.setEntryRestrictions(request.getEntryRestrictions());
        club.setApplyReason(request.getApplyReason());
        clubRepository.save(club);
        return new ClubResponse("success", "俱乐部信息添加成功");
    }

    public List<CreateClubResponse> getCreatedClubs(String studentId) {
        List<Club> clubs = clubRepository.findByClubUser(studentId);
        clubs.forEach(club -> {
            int memberCount = studentClubRepository.countMembersByClubId(club.getClubId());
            club.setMemberCount(memberCount);
        });
        return clubs.stream()
                .map(club -> new CreateClubResponse(
                        club.getClubId(),
                        club.getClubName(),
                        club.getClubLogo(),
                        club.getClubDesc(),
                        club.getClubUser(),
                        club.getCollege(),
                        club.getEntryRestrictions(),
                        club.getMemberCount(),
                        club.getFormattedClubCreate(),
                        club.getClubUserName(),
                        club.getApplyReason(),
                        club.getStatus(),
                        club.getReviewRemark()
                ))
                .collect(Collectors.toList());
    }
}
